package com.papper.common.service.sys;

import com.papper.common.bean.sys.SysCode;
import com.papper.common.cache.CacheConstants;
import com.papper.common.cache.redis.CacheClosureNullDefault;
import com.papper.common.mapper.sys.SysCodeMapper;
import com.papper.common.service.ServiceImpl;
import com.papper.common.utils.tool.StringTool;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * 系统字典业务
 */
@Service("sysCodeService")
public class SysCodeService extends ServiceImpl<SysCodeMapper, SysCode> {

	@Override
	protected void clearCaches(SysCode entity) {
		super.clearCaches(entity);
		String model = getModel();
		cache.delete(CacheConstants.Keys(model, entity.getCodeKey()));
		cache.delete(CacheConstants.Keys(model, entity.getCodeKey(), entity.getParentId()));
		cache.delete(CacheConstants.Keys(model, "PA", entity.getId()));
		cache.delete(CacheConstants.Keys(model, "PA", entity.getParentId()));
	}

	/**
	 * 根据名称获取字典信息.
	 *
	 * @param codeKey the codeKey
	 * @return the sys code
	 */
	public SysCode findByKey(final String codeKey) {
		if (StringTool.isEmpty(codeKey)) {
			return null;
		}
		return cache.getAndSet(new CacheClosureNullDefault<SysCode>() {
			@Override
			public String getKey() {
				return CacheConstants.Keys(getModel(), codeKey);
			}

			@Override
			public SysCode getValue() {
				Example example = new Example(SysCode.class);
				example.createCriteria().andEqualTo("codeKey", codeKey);
				example.setOrderByClause("id desc limit 1");
				return findOne(example);
			}

			@Override
			public Class<SysCode> getTypeReference() {
				return SysCode.class;
			}
		});
	}

	/**
	 * 根据主键获取字典信息.
	 *
	 * @param codeKey  the key
	 * @param parentId the parent id
	 * @return the sys code
	 */
	public SysCode findByKey(final String codeKey, final Long parentId) {
		return cache.getAndSet(new CacheClosureNullDefault<SysCode>() {
			@Override
			public String getKey() {
				return CacheConstants.Keys(getModel(), codeKey, parentId);
			}

			@Override
			public SysCode getValue() {
				Example          example  = new Example(SysCode.class);
				Example.Criteria criteria = example.createCriteria();
				criteria.andEqualTo("codeKey", codeKey);
				criteria.andEqualTo("parentId", parentId);
				example.setOrderByClause("id desc limit 1");
				return findOne(example);
			}

			@Override
			public Class<SysCode> getTypeReference() {
				return SysCode.class;
			}
		});
	}

	/**
	 * 获取子类字典列表.
	 *
	 * @param parentId the parent id
	 * @return the list
	 */
	public List<SysCode> findByParentId(final Long parentId) {
		return cache.getAndSetList(new CacheClosureNullDefault<SysCode>() {
			@Override
			public String getKey() {
				return CacheConstants.Keys(getModel(), "PA", parentId);
			}

			@Override
			public List<SysCode> getValue() {
				Example example = new Example(SysCode.class);
				example.createCriteria().andEqualTo("parentId", parentId);
				example.setOrderByClause("code_sort asc");
				return find(example);
			}

			@Override
			public Class<SysCode> getTypeReference() {
				return SysCode.class;
			}
		});
	}

	/**
	 * 获取子类字典列表.
	 *
	 * @param parentKey the parent key
	 * @return the list
	 */
	public List<SysCode> findChild(String parentKey) {
		SysCode sysCode = findByKey(parentKey);
		if (sysCode == null) {
			return null;
		}
		return findByParentId(sysCode.getId());
	}
}